import React, { useState, useRef, useEffect } from 'react';
import { Input, Modal, message } from 'antd';
import { useAntdTable, useUpdateEffect } from '@umijs/hooks';
import PropTypes from 'prop-types';
import isFunction from 'lodash/isFunction';
import get from 'lodash/get';
import IconFont from '@/components/IconFont';
import SlickTable from '@/components/SlickTable';
import request from '@/utils/request';
import styles from './comboModal.less';

function getTableData({ current, pageSize, method, url, ...rest }) {
  return request(url, {
    method,
    data: {
      // page: current,
      pageNum: current,
      pageSize,
      // rowNum: pageSize,
      sortName: '',
      sortOrder: 'asc',
      ...rest,
    },
  }).then(res => {
    const { success, errMessage, data = {} } = res;
    if (success === true) {
      if (Array.isArray(get(data, 'records'))) {
        return {
          total: data.total,
          data: data.records,
        };
      }
    }
    message.error(errMessage || '数据获取失败');
    return {
      total: 0,
      data: [],
    };
  });
}

function getValue(value, tokenSeparators, label) {
  const result = [];
  if (Array.isArray(value)) {
    value.map(val => {
      return result.push(val[label]);
    });
  } else if (typeof value === 'string') {
    result.push(value);
  }
  return result.join(tokenSeparators);
}

function ComboModal({
  onChange,
  value,
  placeholder = '请选择',
  tokenSeparators,
  disabled,
  readOnly,
  tableProps,
  modalProps,
}) {
  const [selectedRows, setSelectedRows] = useState(value);
  const [keyword, setKeyword] = useState('');
  const [open, setOpen] = useState(false);
  const tableEl = useRef(null);
  const {
    title = '标题',
    width = 800,
    destroyOnClose = false,
    onOk = () => {},
    ...restModalProps
  } = modalProps;
  const {
    method = 'post',
    multiple = false,
    extra = null,
    params = {},
    searchPlaceholder = '输入关键字',
    filterScope = '',
    columns,
    rowKey,
    label,
    url,
    ...restTableProps
  } = tableProps;

  // tableProps格式{dataSource,loading,onChange,pagination:{current,pageSize,total}}
  const { tableProps: tProps } = useAntdTable(
    query => {
      if (!open) {
        return Promise.resolve(1);
      }
      /**
       * query包含 分页和表单值，格式如下：
       * {current: 1,filters: {},pageSize: 2,sorter:{},bulletinTitle:''}
       * expand=true 表示高级搜索；高级搜索无视快捷搜索上的bulletinTitle值；反之一样
       */
      let filterVal = {};
      if (keyword) {
        filterVal = { filterVal: keyword, filterScope };
      }
      return getTableData({ ...query, pageSize: 10, method, url, ...filterVal, ...params });
    },
    [keyword, filterScope, JSON.stringify(params), url, open],
    {
      defaultPageSize: 10,
    }
  );

  const { pagination, ...restTProps } = tProps;

  /**
   * 1、input元素被get包裹 会从props带入onChange方法,selectedRows 保证form取到的值是实时最新的
   * 2、只在更新阶段执行onChange，避免在初始化时触发rule校验（如果被getFieldDecorator包裹）
   */
  useUpdateEffect(() => {
    if (isFunction(onChange)) {
      onChange(selectedRows);
    }
  }, [selectedRows, onChange]);

  /**
   * 外部通过setFieldsValue设置值的时候，即时更新
   */
  useEffect(() => {
    if (Array.isArray(value)) {
      setSelectedRows(value);
    }
  }, [value]);

  return (
    <>
      {readOnly === true ? (
        getValue(selectedRows, tokenSeparators, label)
      ) : (
        <Input
          placeholder={placeholder}
          disabled={disabled}
          // allowClear
          // onChange={e => {
          //   window.tableEl = tableEl;
          //   if (tableEl && tableEl.current) {
          //     tableEl.current.cleanSelectedKeys([], []);
          //   }
          // }}
          suffix={<IconFont type="icon-comboModal" />}
          value={getValue(selectedRows, tokenSeparators, label)}
          onClick={e => {
            e.preventDefault();
            setOpen(true);
          }}
        />
      )}
      <Modal
        title={title}
        destroyOnClose={destroyOnClose}
        width={width}
        centered
        onOk={() => {
          onOk(selectedRows);
          setOpen(false);
        }}
        visible={open}
        onCancel={() => setOpen(false)}
        {...restModalProps}
      >
        <Input.Search
          placeholder={searchPlaceholder}
          allowClear
          className={styles.search}
          onSearch={val => setKeyword(val)}
        />
        <SlickTable
          ref={tableEl}
          extra={extra}
          rowKey={rowKey}
          pick={multiple ? 'checkbox' : 'radio'}
          data={{ pagination }}
          {...restTProps}
          selectedRowKeys={selectedRows.map(row => row[rowKey])}
          onSelectRow={selectedRows => {
            const result = [];
            selectedRows.map(val => result.push(val.orgName));
            setSelectedRows(selectedRows);
          }}
          columns={columns}
          {...restTableProps}
        />
      </Modal>
    </>
  );
}

ComboModal.defaultProps = {
  value: [],
  placeholder: '',
  tokenSeparators: ',',
  disabled: false,
  readOnly: false,
  modalProps: {},
  tableProps: {},
};

ComboModal.propTypes = {
  value: PropTypes.array,
  placeholder: PropTypes.string,
  tokenSeparators: PropTypes.string,
  disabled: PropTypes.bool,
  readOnly: PropTypes.bool,
  modalProps: PropTypes.shape({
    onOk: PropTypes.func.isRequired,
    title: PropTypes.string,
    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    destroyOnClose: PropTypes.bool,
  }),
  tableProps: PropTypes.shape({
    url: PropTypes.string.isRequired,
    method: PropTypes.oneOf(['post', 'get', 'put']),
    multiple: PropTypes.bool,
    searchPlaceholder: PropTypes.string,
    extra: PropTypes.oneOfType([PropTypes.func, PropTypes.element]),
    params: PropTypes.object,
    columns: PropTypes.arrayOf(PropTypes.object).isRequired,
    rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]).isRequired,
    label: PropTypes.string.isRequired,
    filterScope: PropTypes.string,
  }),
};

export default ComboModal;
